package com.situation.controller;

import com.github.pagehelper.PageInfo;
import com.situation.annotation.ControllerEndpoint;
import com.situation.config.ConUtil;
import com.situation.mapper.TbUserMapper;
import com.situation.pojo.DO.*;
import com.situation.pojo.TbUserPage;
import com.situation.pojo.VO.MenuNodeVO;
import com.situation.pojo.VO.UserRoleVO;
import com.situation.pojo.VO.UserVO;
import com.situation.service.LoginLogService;
import com.situation.service.TbUserService;
import com.situation.util.ExcelUtil;
import com.situation.util.JWTUtil;
import com.situation.util.RespUtil;
import com.sun.org.apache.regexp.internal.RE;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author qian
 * @date 2021/12/7 10:48
 */
@RestController
@RequestMapping("/api/user")
public class TbUserController {
    @Autowired
    private TbUserService tbUserService;
    @Autowired
    private LoginLogService loginLogService;

    @ControllerEndpoint(exceptionMessage = "添加用户失败", operation = "添加用户")
    @PostMapping("/add")
    @RequiresPermissions({"user:add"})
    public RespUtil addTbUser(TbUser user) {
        int i = tbUserService.addTbUser(user);
        if (i > 0) {
            return RespUtil.ok();
        }
        return RespUtil.fail();
    }

    /***
     * @Description: 删除用户
     * @Param: [id]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/7
     */
    @ControllerEndpoint(exceptionMessage = "删除用户失败", operation = "删除用户")
    @DeleteMapping("/delete/{id}")
    @RequiresPermissions({"user:delete"})
    public RespUtil deleteTbUser(@PathVariable Long id) {
        int i = tbUserService.deleteTbUser(id);
        if (i < 1) {
            return RespUtil.fail();
        }
        return RespUtil.ok().setData("删除成功");
    }


    /**
     * 数据回填  查询单个   ===已测===
     *
     * @param id
     * @return
     */
    @GetMapping("/edit/{id}")
    @RequiresPermissions({"user:edit"})
    public RespUtil edit(@PathVariable Long id) {
        UserVO userVO = tbUserService.queryUserVoById(id);
        return RespUtil.ok().setData(userVO);
    }

    /**
     * 修改用户   === 已测====
     *
     * @param id
     * @param user
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "更新用户失败", operation = "更新用户")
    @PutMapping("/update/{id}")
    @RequiresPermissions({"user:update"})
    public RespUtil update(@PathVariable Long id, TbUser user) {
        user.setId(id);
        int i = tbUserService.updateTbUser(user);
        return RespUtil.ok();
    }


    /**
     * 导出用户表数据excel
     *
     * @param response
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "导出用户execl失败", operation = "导出用户execl")
    @RequestMapping("/excel")
    @RequiresPermissions("user:export")
    public void excel(HttpServletResponse response) {
        List<TbUser> tbUserList = tbUserService.findAllTbUser();
        List<List<String>> excelData = new ArrayList<>();
        List<String> headList = new ArrayList<>();
        headList.add("编号");
        headList.add("用户名");
        headList.add("昵称");
        headList.add("邮箱");
        headList.add("电话号码");
        headList.add("创建时间");
        headList.add("修改时间");
        headList.add("性别");
        headList.add("密码盐值");
        headList.add("用户类型");
        headList.add("用户密码");
        headList.add("出生日期");
        headList.add("头像url");
        excelData.add(headList);
        for (TbUser tbUser : tbUserList) {
            List<String> list = new ArrayList<>();
            long id = tbUser.getId();
            int tempId = (int) id;
            list.add(Integer.toString(tempId));
            list.add(tbUser.getUsername());
            list.add(tbUser.getNickname());
            list.add(tbUser.getEmail());
            list.add(tbUser.getPhoneNumber());
            list.add(tbUser.getCreateTime().toString());
            list.add(tbUser.getModifiedTime().toString());
            if (tbUser.getSex() == 0) {
                list.add("男");
            } else {
                list.add("女");
            }
            list.add(tbUser.getSalt());
            if (tbUser.getType() == 0) {
                list.add("超级管理员");
            } else {
                list.add("系统用户");
            }
            list.add(tbUser.getPassword());
            list.add(tbUser.getBirth().toString());
            list.add(tbUser.getAvatar());
            excelData.add(list);
        }
        String sheetName = "用户列表";
        String fileName = "用户信息统计表";
        try {
            ExcelUtil.exportExcel(response, excelData, sheetName, fileName, 15);
        } catch (IOException e) {
//            logger.info("导出失败");
            System.out.println("导出失败");
        }
    }


    /***
     * @Description: 用户查询菜单
     * @Param: [tbUser, pageNum, pageSize]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/8
     */
    @GetMapping("/findMenu")
    public RespUtil findAllMenu() {
        List<MenuNodeVO> menuTreeVOS = tbUserService.findMenu();
        System.out.println("++++++++++++++++++++++");
        System.out.println("++++++++++++++++++++++");
        System.out.println("++++++++++++++++++++++");
        menuTreeVOS.forEach(System.out::println);
        return RespUtil.ok().setData(menuTreeVOS);
    }

    /***
     * @Description: 多条件模糊查询
     * @Param: [userVo, pageNum, pageSize]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/8
     */
    @GetMapping("/findUserList")
    public RespUtil findUserList(TbUser user,
                                 @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                 @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        PageInfo<UserVO> userList = tbUserService.findUserList(user, pageNum, pageSize);
        if (userList == null) {
            return RespUtil.fail().setData("查询失败");
        }
        return RespUtil.ok().setData(userList);
    }

    /***
     * @Description: 查询登入用户信息
     * @Param: [tbUser]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/8
     */
    @GetMapping("/info")
    public RespUtil findInfo() {
        UserRoleVO userInfo = tbUserService.userInfo();
        if (userInfo == null) {
            return RespUtil.fail();
        }
        return RespUtil.ok().setData(userInfo);
    }

    /***
     * @Description: 给指定id用户分配角色
     * @Param: [tbUserRole]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/8
     */
    @ControllerEndpoint(exceptionMessage = "添加用户角色失败", operation = "添加用户角色")
    @PostMapping("/{id}/assignRoles")
    @RequiresPermissions({"user:assign"})
    public RespUtil addTbUserRole(@PathVariable Long id, Long[] rids) {
        List<Long> longList = Arrays.asList(rids);
        int i = tbUserService.addTbUserRole(id, longList);
        if (i == longList.size()) {
            return RespUtil.ok();
        }
        return RespUtil.fail();
    }

    /***
     * @Description: 通过用户id查询现有角色
     * @Param: [id]
     * @return: com.situation.util.RespUtil
     * @Author: 赵启岸
     * @Date: 2021/12/8
     */
    @GetMapping("/{id}/roles")
    public RespUtil findRoleById(@PathVariable("id") Long id) {
        List<TbRole> roleList = tbUserService.findRoleById(id);
        if (roleList == null) {
            return RespUtil.fail();
        }
        return RespUtil.ok().setData(roleList);
    }

    /**
     * 是否禁用   true 禁用    false   启用
     *
     * @param id
     * @param status
     * @return
     */
    @ControllerEndpoint(exceptionMessage = "更新用户状态失败", operation = "更新用户状态")
    @RequiresPermissions({"user:status"})
    @PutMapping("/updateStatus/{id}/{status}")
    public RespUtil updateStatus(@PathVariable Long id, @PathVariable Boolean status) {
        if (status) {
            tbUserService.updateStatus(id, 0);
        } else {
            tbUserService.updateStatus(id, 1);
        }
        return RespUtil.ok();
    }

    @PostMapping("/login")
    public RespUtil login(@RequestBody Login login, HttpServletRequest request) {

        Subject currentUser = SecurityUtils.getSubject();
        System.out.println(login.getUsername());
        System.out.println(login.getPassword());
        //封装凭证
        UsernamePasswordToken token = new UsernamePasswordToken(login.getUsername(), login.getPassword());
        //身份认证

        currentUser.login(token);
        //认证失败：抛异常

        // 登录日志
        loginLogService.add(request);

        return RespUtil.ok().setData(ConUtil.token);
    }


}
